#include "thread_pool.h"
#include <pthread.h>

int queueInit(task_queue_t* que) //初始化
{
    if(que){
        que->pFront =NULL;
        que->pRear =NULL;
        que->queSize =0;
        que->flag=1;
        int ret = pthread_mutex_init(&que->mutex,NULL);
        THREAD_ERROR_CHECK(ret,"pthread_mutex_init");

        ret = pthread_cond_init(&que->cond,NULL);
        THREAD_ERROR_CHECK(ret,"pthread_cond_init");
    }
    return 0;
}
int queueDestroy(task_queue_t* que)//销毁任务队列
{
    if(que){
        int ret = pthread_mutex_destroy(&que->mutex);
        THREAD_ERROR_CHECK(ret,"pthread_mutex_destroy");

        ret=pthread_cond_destroy(&que->cond);
        THREAD_ERROR_CHECK(ret,"pthread_cond_destroy");

    }
    return 0;
}
int queueIsEmpty(task_queue_t* que) //判断是否为空
{
    return que->queSize==0;
}
int taskSize(task_queue_t* que) //获取队列中的任务数量
{
    return que->queSize;
}
int taskEnque(task_queue_t* que,task_t* ptask)// 将任务加入队列
{
    int ret = pthread_mutex_lock(&que->mutex); //先上锁

    THREAD_ERROR_CHECK(ret,"pthread_mutex_lock");

    if(queueIsEmpty(que)){
        //如果为空
        que->pFront = que->pRear=ptask;
    }else{
        //不为空
        que->pFront->pNext =ptask;
        que->pRear = ptask;
    }
    que->queSize++; //长度加一
    ret = pthread_mutex_unlock(&que->mutex); //解锁
                                             
    THREAD_ERROR_CHECK(ret,"pthread_mutex_unlock");
    return 0;
}

task_t* taskDeque(task_queue_t* que) //从队列中取出任务
{
    int ret = pthread_mutex_lock(&que->mutex);
    THREAD_ERROR_CHECK(ret,"pthread_mutex_lock");
    task_t* pret;
    while(que->flag && queueIsEmpty(que)){ //虚假唤醒
        //释放que->mutex互斥锁
           // 阻塞当前线程，等待条件变量que->cond被唤醒
           // 当被唤醒后，重新获取que->mutex互斥锁
        pthread_cond_wait(&que->cond,&que->mutex);
    }
    if(que->flag){
        //元素出队列操作
        pret = que->pFront;
        if(taskSize(que)==1){
            que->pFront=que->pRear=NULL;
        }else
        {
            que->pFront=que->pFront->pNext;
        }
        que->queSize--;
    }else{
        pret=NULL;
    }
    
    //解锁
    ret =pthread_mutex_unlock(&que->mutex);
    THREAD_ERROR_CHECK(ret,"pthread_mutex_unlock");
    return pret;
    
}



//主线程调用
int broadcastALL(task_queue_t * que)
{
    //先修改要退出的标识位
    que->flag = 0;
    int ret = pthread_cond_broadcast(&que->cond);
    THREAD_ERROR_CHECK(ret, "pthread_cond_broadcast");

    return 0;
}
